package com.shinhye.smartsms;

import java.util.Date;
import java.util.HashSet;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.widget.CursorAdapter;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.shinhye.smartsms.utils.CommonUtils;
import com.shinhye.smartsms.utils.MyAsyncQueryHandler;
import com.shinhye.smartsms.utils.SmsUris;

public class ConversationActivity extends Activity implements OnClickListener, OnItemLongClickListener{
	private final int MENUID_SEARCH = 0x001;
	private final int MENUID_EDIT = 0x002;
	private final int MENUID_CANCELEDIT = 0x003;
	private final int COLUMN_SNIPPET = 0;
	private final int COLUMN_ID = 1;
	private final int COLUMN_MSG_COUNT = 2;
	private final int COLUMN_ADDRESS = 3;
	private final int COLUMN_DATE = 4;
	
	private ListView lv_sms;
	private boolean isEditting;
	private CursorAdapter adapter;
	private Button btn_newsms;
	private Button btn_selectall;
	private Button btn_disselectall;
	private Button btn_delselected;
	private HashSet<Integer> checkedIDs;
	private ProgressDialog dialog;
	private boolean hasCanceled;
	private int[] threadIds;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_conversation);
		checkedIDs = new HashSet<Integer>();
		
		lv_sms = (ListView) findViewById(R.id.lv_sms);
		btn_newsms = (Button) findViewById(R.id.btn_newsms);
		btn_selectall = (Button) findViewById(R.id.btn_selectall);
		btn_disselectall = (Button) findViewById(R.id.btn_disselectall);
		btn_delselected = (Button) findViewById(R.id.btn_delselected);
		
		adapter = new MyCursorAdapter(this, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
		lv_sms.setAdapter(adapter);
		lv_sms.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if(isEditting) {
					ViewHolder holder = (ViewHolder) view.getTag();
					if(holder.cb_sms.isChecked()) {
						checkedIDs.remove(holder._id);
						holder.cb_sms.setChecked(false);
					} else {
						checkedIDs.add(holder._id);
						holder.cb_sms.setChecked(true);
					}
				} else {
					Intent intent = new Intent(ConversationActivity.this, ConversationDetailActivity.class);
					Cursor cursor = adapter.getCursor();
					cursor.moveToPosition(position);
					intent.putExtra("address", cursor.getString(COLUMN_ADDRESS));
					startActivity(intent);
				}
				flushState();
			}
		});
		lv_sms.setOnItemLongClickListener(this);
		
		btn_newsms.setOnClickListener(this);
		btn_selectall.setOnClickListener(this);
		btn_disselectall.setOnClickListener(this);
		btn_delselected.setOnClickListener(this);
		
		Intent intent = getIntent();
		threadIds = intent.getIntArrayExtra("threadIds");
		getData();
	}
	
	protected String getGroupFromThreadId(int _id) {
		String name = null;
		Cursor cursor = getContentResolver().query(SmsUris.THREAD_URI, new String[]{"group_id"}, "thread_id=?", new String[]{_id + ""}, null);
		if(cursor.moveToNext()) {
			int groupId = cursor.getInt(0);
			Cursor nameCursor = getContentResolver().query(SmsUris.GROUP_URI, new String[]{"name"}, "_id=?", new String[]{groupId + ""}, null);
			if(nameCursor.moveToNext()) {
				name = nameCursor.getString(0);
			}
		}
		return name;
	}

	private void getData() {
		MyAsyncQueryHandler asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver());
		String[] projection = new String[]{
				"sms.body AS snippet",
				"sms.thread_id AS _id",
				"groups.msg_count AS msg_count",
				"address AS address",
				"date AS date"
		};
		String selection = null;
		String[] selectionArgs = null;
		if(threadIds != null) {
			StringBuffer sb = new StringBuffer();
			sb.append("thread_id in (");
			selectionArgs = new String[threadIds.length];
			for(int i = 0; i < threadIds.length; i++) {
				sb.append("?,");
				selectionArgs[i] = threadIds[i] + "";
			}
			sb.deleteCharAt(sb.lastIndexOf(","));
			sb.append(")");
			selection = sb.toString().trim();
		}
		asyncQueryHandler.startQuery(0, adapter, SmsUris.CONVERSATIONS_URI, projection, selection, selectionArgs, "date desc");
	}

	class MyCursorAdapter extends CursorAdapter {

		//在CursorAdapter中cursor执行requery方法后才会导致listview页面更新，且requery方法在调用的线程中执行。如果flags为FLAG_AUTO_REQUERY，
		//就会执行requery方法，可能导致ANR异常。所以使用FLAG_REGISTER_CONTENT_OBSERVER，在内容改变时，重新异步获取cursor，并设置重新设置给adapter。
		public MyCursorAdapter(Context context, Cursor c, int flags) {
			super(context, c, flags);
		}

		@Override
		protected void onContentChanged() {
			getData();
		}
		
		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			View view = View.inflate(ConversationActivity.this, R.layout.item_conversation, null);
			ViewHolder holder = new ViewHolder();
			holder.cb_sms = (CheckBox) view.findViewById(R.id.cb_sms);
			holder.iv_contact = (ImageView) view.findViewById(R.id.iv_contact);
			holder.tv_name = (TextView) view.findViewById(R.id.tv_name);
			holder.tv_msg = (TextView) view.findViewById(R.id.tv_msg);
			holder.tv_date = (TextView) view.findViewById(R.id.tv_date);
			view.setTag(holder);
			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			ViewHolder holder = (ViewHolder) view.getTag();
			String snippet = cursor.getString(COLUMN_SNIPPET);
			int _id = cursor.getInt(COLUMN_ID);
			int msg_count = cursor.getInt(COLUMN_MSG_COUNT);
			String address = cursor.getString(COLUMN_ADDRESS);
			long date = cursor.getLong(COLUMN_DATE);
			
			//holder保存id
			holder._id = _id;
			
			//设置复选框
			if(isEditting) {
				holder.cb_sms.setVisibility(View.VISIBLE);
				holder.cb_sms.setChecked(checkedIDs.contains(_id));
			} else {
				holder.cb_sms.setVisibility(View.GONE);
			}
			
			//联系人或电话号码, 联系人头像
			String contactName = CommonUtils.getContactName(getContentResolver(), address);
			if(TextUtils.isEmpty(contactName)) {
				holder.tv_name.setText(address + " (" + msg_count + ")");
				holder.iv_contact.setImageResource(R.drawable.ic_unknow_contact_picture);
			} else {
				holder.tv_name.setText(contactName + " (" + msg_count + ")");
				Bitmap photo = CommonUtils.getContactPhoto(getContentResolver(), address);
				if(photo == null)
					holder.iv_contact.setImageResource(R.drawable.ic_contact_picture);
				else
					holder.iv_contact.setImageBitmap(photo);
			}
			
			//信息内容片段
			holder.tv_msg.setText(snippet);
			
			//时间
			String formattedDate;
			if(DateUtils.isToday(date)) {
				formattedDate = DateFormat.getTimeFormat(context).format(new Date(date));
			} else {
				formattedDate = DateFormat.getDateFormat(context).format(new Date(date));
			}
			holder.tv_date.setText(formattedDate);
		}
		
	}
	class ViewHolder {
		int _id;
		CheckBox cb_sms;
		ImageView iv_contact;
		TextView tv_name;
		TextView tv_msg;
		TextView tv_date;
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENUID_SEARCH, Menu.NONE, "搜索");
		menu.add(0, MENUID_EDIT, Menu.NONE, "编辑");
		menu.add(0, MENUID_CANCELEDIT, Menu.NONE, "取消编辑");
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		if(isEditting) {
			menu.findItem(MENUID_SEARCH).setVisible(false);
			menu.findItem(MENUID_EDIT).setVisible(false);
			menu.findItem(MENUID_CANCELEDIT).setVisible(true);
		} else {
			menu.findItem(MENUID_SEARCH).setVisible(true);
			menu.findItem(MENUID_EDIT).setVisible(true);
			menu.findItem(MENUID_CANCELEDIT).setVisible(false);
		}
		return super.onPrepareOptionsMenu(menu);
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()) {
		case MENUID_SEARCH:
			onSearchRequested();
			break;
		case MENUID_EDIT:
			isEditting = true;
			flushState();
			break;
		case MENUID_CANCELEDIT:
			isEditting = false;
			flushState();
			break;
		}
		return super.onOptionsItemSelected(item);
	}
	
	private void flushState() {
		if(isEditting) {
			btn_newsms.setVisibility(View.GONE);
			btn_selectall.setVisibility(View.VISIBLE);
			btn_disselectall.setVisibility(View.VISIBLE);
			btn_delselected.setVisibility(View.VISIBLE);
			
			btn_disselectall.setEnabled(checkedIDs.size() != 0);
			btn_delselected.setEnabled(checkedIDs.size() != 0);
			btn_selectall.setEnabled(checkedIDs.size() != lv_sms.getCount());
		} else {
			btn_newsms.setVisibility(View.VISIBLE);
			btn_selectall.setVisibility(View.GONE);
			btn_disselectall.setVisibility(View.GONE);
			btn_delselected.setVisibility(View.GONE);
			
			checkedIDs.clear();
		}
	}
	
	@Override
	public void onBackPressed() {
		if(isEditting) {
			isEditting = false;
			flushState();
		} else {
			super.onBackPressed();
		}
	}

	@Override
	public void onClick(View v) {
		switch(v.getId()) {
		case R.id.btn_newsms:
			Intent intent = new Intent(this, CreateSMSActivity.class);
			startActivity(intent);
			break;
		case R.id.btn_selectall:
			Cursor cursor = adapter.getCursor();
			cursor.moveToPosition(-1);
			while(cursor.moveToNext()) {
				int _id = cursor.getInt(COLUMN_ID);
				checkedIDs.add(_id);
			}
			System.out.println(checkedIDs);
			adapter.notifyDataSetChanged();
			flushState();
			break;
		case R.id.btn_disselectall:
			checkedIDs.clear();
			adapter.notifyDataSetChanged();
			flushState();
			break;
		case R.id.btn_delselected:
			showDeleteDialog();
			break;
		}
	}

	private void showDeleteDialog() {
		Builder builder = new AlertDialog.Builder(this);
		builder.setIcon(android.R.drawable.ic_dialog_alert);
		builder.setTitle("删除信息");
		builder.setMessage("您确定要删除选中的信息吗？");
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				showDeleteProgress();
			}
		});
		builder.setNegativeButton("取消", null);
		
		builder.show();
	}

	protected void showDeleteProgress() {
		dialog = new ProgressDialog(this);
		dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		dialog.setIcon(android.R.drawable.ic_dialog_info);
		dialog.setTitle("删除中，请稍候...");
		dialog.setMax(checkedIDs.size());
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				hasCanceled = true;
				System.out.println("to cancel");
			}
		});
		dialog.setOnDismissListener(new OnDismissListener() {
			@Override
			public void onDismiss(DialogInterface dialog) {
				System.out.println("dismiss~~");
				isEditting = false;
				flushState();
			}
		});
		
		dialog.show();
		deleteSMS();
	}

	private void deleteSMS() {
		new Thread() {
			@Override
			public void run() {
				for(int id : checkedIDs) {
					SystemClock.sleep(1000);
					if(hasCanceled) {
						System.out.println("canceled!");
						hasCanceled = false;
						break;
					}
					getContentResolver().delete(SmsUris.SMS_URI, "thread_id=?", new String[]{id + ""});
					System.out.println("delete!");
					dialog.incrementProgressBy(1);
					System.out.println("increased..");
				}
				
				dialog.dismiss();
			}
		}.start();
	}
	
	@Override
	public boolean onItemLongClick(AdapterView<?> parent, View view,
			int position, long id) {
		//get the thread id
		Cursor curCursor = (Cursor) adapter.getItem(position);
		final int _id = curCursor.getInt(COLUMN_ID);
		
		//if this thread has already in a group
		String groupName = getGroupFromThreadId(_id);
		if(!TextUtils.isEmpty(groupName)) {
			Toast.makeText(ConversationActivity.this, "该会话以在群组" + groupName + "中！", Toast.LENGTH_SHORT).show();
			return true;
		}
		
		//query all group
		Cursor groCursor = getContentResolver().query(SmsUris.GROUP_URI, new String[]{"_id", "name"}, null, null, null);
		final int[] itemids = new int[groCursor.getCount()];
		final String[] items = new String[groCursor.getCount()];
		while(groCursor.moveToNext()) {
			itemids[groCursor.getPosition()] = groCursor.getInt(0);
			items[groCursor.getPosition()] = groCursor.getString(1);
		}
		
		//show dialog
		AlertDialog.Builder builder = new AlertDialog.Builder(ConversationActivity.this);
		builder.setItems(items, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				ContentValues cv = new ContentValues();
				cv.put("group_id", itemids[which]);
				cv.put("thread_id", _id);
				getContentResolver().insert(SmsUris.THREAD_URI, cv);
				Toast.makeText(ConversationActivity.this, "添加到群组" + items[which] + "成功！", Toast.LENGTH_SHORT).show();
			}
		});
		
		builder.show();
		return true;
	}

}
